﻿using Aliyun.Acs.Core.Auth;
using Aliyun.Acs.Core.Profile;
using Aliyun.OSS;
using Aliyun.OSS.Common;
using JNPF.Utils.Extensions;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Utilities.Zlib;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.IO;
using System.Net.Sockets;
using System.Reflection;
using System.Security.AccessControl;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using ZXing;
using ZXing.Aztec.Internal;
using static Org.BouncyCastle.Math.EC.ECCurve;

namespace JNPF.Utils
{
    public class WeChatHttpHelper
    {
        /// <summary>
        /// 获取用户token
        /// </summary>
        /// <param name="type">0:小程序  1：公共号</param>
        /// <returns></returns>
        public static string Token(int type = 0)
        {
            try
            {
                string appid = string.Empty;

                string secret = string.Empty;

                if (type == 0)
                {
                    appid = Appsettings.app(new string[] { "JNPF_App", "appid" }).ToString();
                    secret = Appsettings.app(new string[] { "JNPF_App", "secret" }).ToString();
                }
                else
                {
                    appid = Appsettings.app(new string[] { "JNPF_App", "zzhappid" }).ToString();
                    secret = Appsettings.app(new string[] { "JNPF_App", "zzhsecret" }).ToString();
                }


                string cacheKey = "zzhtoken" + appid;
                string token = CacheFactory.Cache.Get<string>(cacheKey);
                if (string.IsNullOrEmpty(token))
                {
                    string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, secret);
                    JObject jo = JObject.Parse(HttpMethods.HttpGet(url));

                    LogFactory.GetLogger().Error("Token:" + jo.ToJson());

                    token = jo["access_token"].ToString();
                    //保存到缓存一个小时
                    CacheFactory.Cache.Insert(cacheKey, token, DateTime.Now.AddMinutes(60).TimeOfDay);
                }
                return token;
            }
            catch (Exception ex)
            {
                LogFactory.GetLogger().Error("Token" + ex.ToString());
            }
            return "";
        }

        /// <summary>
        /// 清空token
        /// </summary>
        public static void RemoveToken()
        {
            string appid = Appsettings.app(new string[] { "JNPF_App", "appid" }).ToString();

            string cacheKey = "zzhtoken" + appid;

            CacheFactory.Cache.Remove(cacheKey);
        }


        /// <summary>
        /// 清空token
        /// </summary>
        public static void ZghRemoveToken()
        {
            string appid = Appsettings.app(new string[] { "JNPF_App", "zzhappid" }).ToString();

            string cacheKey = "zzhtoken" + appid;

            CacheFactory.Cache.Remove(cacheKey);
        }


        /// <summary>
        /// 生成小程序码 B 二维码那种
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Tuple<string, string> QrcodeCreateC(string id)
        {
            try
            {
                //C码
                string url = $"https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + Token();
                Tuple<string, string> tuple = PostMoths(url, "{\"path\":\"pagesJiushi/partner/addpartner/addpartner?id=" + id + "\"}", id);
                return tuple;
            }
            catch (Exception ex)
            {
                return QrcodeCreateCTwo(id);
            }
        }


        /// <summary>
        /// 生成小程序码 B 二维码那种
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static Tuple<string, string> QrcodeCreateCTwo(string id)
        {
            try
            {
                //先清空token,再走一遍
                RemoveToken();
                //C码
                string url = $"https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=" + Token();
                Tuple<string, string> tuple = PostMoths(url, "{\"path\":\"pagesJiushi/partner/addpartner/addpartner?id=" + id + "\"}", id);
                return tuple;
            }
            catch (Exception ex)
            {
                return new Tuple<string, string>("报错啦", ex.ToString());
            }
        }




        /// <summary>
        /// 图片路径|文件名称|base64|图片绝对路径
        /// </summary>
        /// <param name="url"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public static Tuple<string, string> PostMoths(string url, string param, string id)
        {


            //string mapPath = "/CodeGenerate/" + id + ".png";
            //// 获取当前文件路径
            //string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            //// 通过程序集位置获取（单文件发布时可能不可靠）
            //string path = assemblyPath + mapPath;
            //path = path.Replace("/", "\\");

            //Directory.CreateDirectory(assemblyPath + "/CodeGenerate");

            //if (!File.Exists(path))
            //{
            string strURL = url;
            System.Net.HttpWebRequest request;
            request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strURL);
            request.Method = "POST";
            request.ContentType = "application/json;charset=UTF-8";
            string paraUrlCoded = param;
            byte[] payload;
            payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
            request.ContentLength = payload.Length;
            System.IO.Stream writer = request.GetRequestStream();
            writer.Write(payload, 0, payload.Length);
            writer.Close();
            System.Net.HttpWebResponse response;
            response = (System.Net.HttpWebResponse)request.GetResponse();
            System.IO.Stream stream = response.GetResponseStream();//返回图片数据流

            var endpoint = "oss-cn-shanghai.aliyuncs.com";
            var accessKeyId = "LTAI5tBfFwMAuorfSKNb4qbH";
            var accessKeySecret = "WF0Gb2ygZYTDTcnTouzcQaYFhblr1T";
            var bucketName = "jsszgj";
            const string region = "cn-shanghai";


            // 创建ClientConfiguration实例，按照您的需要修改默认参数。
            var conf = new ClientConfiguration();

            // 设置v4签名。
            conf.SignatureVersion = SignatureVersion.V4;

            // 创建OssClient实例。
            var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
            client.SetRegion(region);
            try
            {
                // 上传文件。
                var resul = client.PutObject(bucketName, id + ".png", stream);


                return new Tuple<string, string>($"https://{bucketName}.oss-cn-shanghai.aliyuncs.com/{id}.png", $"https://{bucketName}.oss-cn-hangzhou.aliyuncs.com/{id}.png");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Put object failed, {0}", ex.Message);


                LogFactory.GetLogger().Error("生成图片报错" + ex.ToString());
            }

            return new Tuple<string, string>("", "");



            //Image img = Image.FromStream(stream);

            //img.Save(path);
            // }
            //string WebRootUrl = Appsettings.app(new string[] { "JNPF_App", "WebRootUrl" }).ToString();
            //WebRootUrl = WebRootUrl.Substring(0, WebRootUrl.Length - 1); //最后一个斜杠不要
            //return new Tuple<string, string>(WebRootUrl + mapPath, path);
        }




        /// <summary>
        /// 根据openid获取用户信息
        /// </summary>
        /// <param name="openId"></param>
        public static RQUserInfoResponse UserInfo(string openId)
        {
            string token = Token(1);
            var relUri = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN", token, openId);

            RQUserInfoResponse rQUserInfoResponse = HttpMethods.HttpGet(relUri).ToObject<RQUserInfoResponse>();

            if (rQUserInfoResponse == null || string.IsNullOrEmpty(rQUserInfoResponse.openid))
            {
                ZghRemoveToken(); //清空公众号token 重新再来一次
                return UserInfo1(openId);
            }

            return rQUserInfoResponse;
        }



        /// <summary>
        /// 根据openid获取用户信息
        /// </summary>
        /// <param name="openId"></param>
        public static RQUserInfoResponse UserInfo1(string openId)
        {
            string token = Token(1);
            var relUri = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN", token, openId);

            RQUserInfoResponse rQUserInfoResponse = HttpMethods.HttpGet(relUri).ToObject<RQUserInfoResponse>();

            if (rQUserInfoResponse == null || string.IsNullOrEmpty(rQUserInfoResponse.openid))
            {
                //ZghRemoveToken(); //清空公众号token 重新再来一次
                //UserInfo(openId);
            }

            return rQUserInfoResponse;
        }



        /// <summary>
        /// code 换取 session_key  小程序
        /// </summary>
        /// <param name="loginCode"></param>
        /// <returns></returns>
        public static async Task<Code2SessionResponse> GetJsCode2SessionAsync(string loginCode)
        {
            string appid = Appsettings.app(new string[] { "JNPF_App", "appid" }).ToString();
            string secret = Appsettings.app(new string[] { "JNPF_App", "secret" }).ToString();


            string relUri = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid + "&secret=" + secret + "&js_code=" + loginCode + "&grant_type=authorization_code";

            return HttpMethods.HttpGet(relUri).ToObject<Code2SessionResponse>();

        }



        /// <summary>
        /// 分配数据
        /// </summary>
        /// <param name="allotRecordsEntity"></param>
        /// <param name="openId"></param>
        public static string SendtemplateMessage(string openId, int id, string data, string data1, string data2)
        {
            var relUri = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + Token(1);
            string jsonStr = "{\"touser\":\"" + openId + "\",\"template_id\":\"wvLY-jnR_SLPThCmb92CqmbeBhfhC26461A1Tc5mOug\",\"miniprogram\":{\"appid\":\"wxc442c6732bbe6ad3\",\"pagepath\":\"/pagesJiushi/demand/subpage/demanddetail?id=" + id + "\"}," +

                 "\"data\":{\"character_string2\":{\"value\":\"" + data + "\"}," +
                 "\"time5\":{\"value\":\"" + data1 + "\"}," +
                 "\"thing7\": {\"value\":\"" + data2 + "\"}}}";


            string msg = HttpMethods.HttpPost(relUri, jsonStr);
            JObject jo = JObject.Parse(msg);

            //若报错重新推送
            if (jo["errcode"].ToInt() == 40001)
            {
                ZghRemoveToken();


                return SendtemplateMessageTest(openId, id, data, data1, data2);
            }

            return jo["errmsg"].ToString();

        }


        /// <summary>
        /// 分配数据
        /// </summary>
        /// <param name="allotRecordsEntity"></param>
        /// <param name="openId"></param>
        public static string SendtemplateMessageTest(string openId, int id, string data, string data1, string data2)
        {
            var relUri = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + Token(1);
            string jsonStr = "{\"touser\":\"" + openId + "\",\"template_id\":\"wvLY-jnR_SLPThCmb92CqmbeBhfhC26461A1Tc5mOug\",\"miniprogram\":{\"appid\":\"wxc442c6732bbe6ad3\",\"pagepath\":\"/pagesJiushi/demand/subpage/demanddetail?id=" + id + "\"}," +

                  "\"data\":{\"character_string2\":{\"value\":\"" + data + "\"}," +
                 "\"time5\":{\"value\":\"" + data1 + "\"}," +
                 "\"thing7\": {\"value\":\"" + data2 + "\"}}}";

            string msg = HttpMethods.HttpPost(relUri, jsonStr);
            JObject jo = JObject.Parse(msg);

            //若报错重新推送
            if (jo["errcode"].ToInt() == 40001)
            {

            }

            return jo["errmsg"].ToString();

        }



    }


    public class Code2SessionResponse
    {
        /// <summary>
        /// 会话密钥
        /// </summary>
        public string session_key { get; set; }
        /// <summary>
        /// 用户唯一标识
        /// </summary>
        public string openid { get; set; }
        /// <summary>
        /// 用户在开放平台的唯一标识符。本字段在满足一定条件的情况下才返回
        /// </summary>
        public string unionid { get; set; }

        public string errcode { get; set; }

        public string errmsg { get; set; }

    }



    /// <summary>
    /// 公众号用户信息
    /// </summary>
    public class RQUserInfoResponse
    {
        /// <summary>
        /// 用户是否订阅该公众号标识，值为0时，代表此用户没有关注该公众号，拉取不到其余信息。
        /// </summary>
        public int subscribe { get; set; }

        /// <summary>
        /// 用户的标识，对当前公众号唯一
        /// </summary>
        public string openid { get; set; }

        /// <summary>
        /// 用户的昵称
        /// </summary>
        public string nickname { get; set; }
        /// <summary>
        /// 	用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
        /// </summary>
        public int sex { get; set; }
        /// <summary>
        /// 用户语言
        /// </summary>
        public string language { get; set; }

        /// <summary>
        /// 城市
        /// </summary>
        public string city { get; set; }

        /// <summary>
        /// 城市
        /// </summary>
        public string province { get; set; }

        /// <summary>
        /// 用户所在国家
        /// </summary>
        public string country { get; set; }

        /// <summary>
        /// 用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），用户没有头像时该项为空。若用户更换头像，原有头像URL将失效。
        /// </summary>
        public string headimgurl { get; set; }
        /// <summary>
        /// 用户关注时间，为时间戳。如果用户曾多次关注，则取最后关注时间
        /// </summary>
        public int subscribe_time { get; set; }

        /// <summary>
        /// 只有在用户将公众号绑定到微信开放平台帐号后，才会出现该字段
        /// </summary>
        public string unionid { get; set; }
        /// <summary>
        /// 公众号运营者对粉丝的备注，公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
        /// </summary>
        public string remark { get; set; }
        /// <summary>
        /// 用户所在的分组ID（兼容旧的用户分组接口）
        /// </summary>
        public int groupid { get; set; }
        /// <summary>
        /// 返回用户关注的渠道来源，ADD_SCENE_SEARCH 公众号搜索，ADD_SCENE_ACCOUNT_MIGRATION 公众号迁移，ADD_SCENE_PROFILE_CARD 名片分享，ADD_SCENE_QR_CODE 扫描二维码，ADD_SCENEPROFILE LINK 图文页内名称点击，ADD_SCENE_PROFILE_ITEM 图文页右上角菜单，ADD_SCENE_PAID 支付后关注，ADD_SCENE_OTHERS 其他
        /// </summary>
        public string subscribe_scene { get; set; }
        /// <summary>
        /// 二维码扫码场景（开发者自定义）
        /// </summary>
        public int qr_scene { get; set; }

        /// <summary>
        /// 二维码扫码场景（开发者自定义）
        /// </summary>
        public string qr_scene_str { get; set; }

    }




}
